﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JuniorProject.Models;
using JuniorProject.Models.Employee;
using JuniorProject.Models.Employee.CreationModels;

namespace JuniorProject.Controllers
{
    public class EmployeeController : Controller
    {
        private OIT_Junior_ProjectEntities db = new OIT_Junior_ProjectEntities();

        // GET: /Employee/
        public ActionResult Index()
        {
            Users tempUser = db.Users.Single(x => x.UserName == User.Identity.Name);

            EmployeeAccountModel Eam = EmployeeUserToModel(tempUser);

            Session.SetDataInSession<string>("AccessLevel", Eam.AccessLevel.ToString());
            
            //CHECK FOR USER NOT BEING AN EMPLOYEE
            if (Eam.AccessLevel < 2)
            {
                return RedirectToAction("QuickLogOut", "Account");
            }
            else
            {
                return View(Eam);
            }
        }

        // GET: /Employee/Applications
        public ActionResult Applications()
        {
            var results = (from q in db.Applications where q.StatusID == 23 || q.StatusID == 33 select q).ToList();

            List<HiringSpecialistAppModel> resultsModels = new List<HiringSpecialistAppModel>();
            if (results != null)
            {
                resultsModels = results.ConvertAll(new Converter<Applications, HiringSpecialistAppModel>(DbSearchToHSAMSearch));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(resultsModels);
        }

        // GET: /Employee/Success
        public ActionResult Success(string Type, string returnUrl, int? ID_01)
        {
            string Message;

            switch (Type)
            {
                case "Comment":
                    Message = "Your comment has been posted successfully.";
                    break;
                case "Job":
                    Message = "Your job has been created successfully.";
                    break;
                case "JobPosting":
                    Message = "Your job posting was successful.\nAwaiting approval from management.";
                    break;
                case "Approval":
                    Message = "Your have successfully approved this Job Posting.";
                    break;
                case "Location":
                    Message = "Your store location has been created successfully.";
                    break;
                case "Question":
                    Message = "Your new comment has been posted.";
                    break;
                case "Answer":
                    Message = "Your new answer has been created successfully.";
                    break;
                case "QuestionToJob":
                    Message = "Your changes have been saved.";
                    break;
                case "QuestionToAnswer":
                    Message = "Your changes have been saved.";
                    break;
                case "Edit":
                    Message = "Your changes have been saved.";
                    break;
                case "Hire":
                    Message = "Application has been closed, your selected applicant will be notified of their job offer.";
                    break;
                case "BGSuccess":
                    Message = "Background Check Passed - your changes have been saved.";
                    break;
                case "BGFail":
                    Message = "Background Check Failed - application(s) will be set to denied.";
                    break;
                default:
                    Message = "";
                    break;
            }

            ViewBag.Message = Message;
            ViewBag.ActionName = returnUrl;
            ViewBag.ID_01 = ID_01;

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        #region APPLICATION DETAILS
        // GET: /Employee/ApplicationDetails_Home
        public ActionResult ApplicationDetails_Home(int id)
        {
            Applications tempApplication = db.Applications.Find(id);
            HiringSpecialistAppModel tempHRModel = new HiringSpecialistAppModel(tempApplication,
                                                            tempApplication.Users, tempApplication.JobPostings);

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(tempHRModel);
        }
        
        // GET: /Employee/ApplicationDetails_User
        public ActionResult ApplicationDetails_User(int id)
        {
            EmployeeUserModel Eum = UserToModel(db.Applications.Single(x => x.ID == id).Users);

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(Eum);
        }
        
        // GET: /Employee/ApplicationDetails_Basic
        public ActionResult ApplicationDetails_Basic(int id)
        {
            EmployeeBasicApplicationModel Ebam = BasicApplicationInfoToApplicationModel(db.Applications.Single(x => x.ID == id).Users.BasicApplicationInfo.First());

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(Ebam);
        }
        
        // GET: /Employee/ApplicationDetails_Detailed
        public ActionResult ApplicationDetails_Detailed(int id)
        {
            EmployeeDetailedApplicationModel Edam = DetailedApplicationToDetailedApplicationModel(db.Applications.Single(x => x.ID == id));

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(Edam);
        }
        
        // GET: /Employee/ApplicationDetails_Posting
        public ActionResult ApplicationDetails_Posting(int id)
        {
            EmployeeJobPostingModel Ejm = JobPostingToModel(db.Applications.Single(x => x.ID == id).JobPostings);

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(Ejm);
        }
        
        // GET: /Employee/ApplicationDetails_Questionnaire
        public ActionResult ApplicationDetails_Questionnaire(int id)
        {
            List<UserResponses> tempQuestionnaireList =
                (from q in db.UserResponses where q.ApplicationID == id select q).ToList();
            EQMList EqmList = new EQMList();
            if (tempQuestionnaireList != null)
            {
                EqmList.Questions = tempQuestionnaireList.ConvertAll(new Converter<UserResponses,
                                                EmployeeQuestionnaireModel>(QuestionnaireToModel));
            }

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(EqmList);
        }
        
        // GET: /Employee/ApplicationDetails_Comments
        public ActionResult ApplicationDetails_Comments(int id)
        {
            List<Comments> tempCommentList =
                (from q in db.Comments where q.ApplicationID == id select q).ToList();
            ECMList EcmList = new ECMList();
            if (tempCommentList != null)
            {
                EcmList.Comments = tempCommentList.ConvertAll(new Converter<Comments, 
                                                EmployeeCommentModel>(CommentToModel));
            }

            ViewData.Add("ApplicationID", id);
            ViewData.Add("PostingID", db.Applications.Single(x => x.ID == id).JobPostings.ID);
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(EcmList);
        }
        #endregion

        #region COMMENTS
        // GET: /Employee/AddComment
        public ActionResult AddComment(int id)
        {
            ViewData["ApplicationID"] = id;
            ViewData["EmployeeID"] = db.Users.Single(x => x.UserName == User.Identity.Name).ID;
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        // POST: /Employee/AddComment
        [HttpPost]
        public ActionResult AddComment(Create_CommentModel model, int AppID, int EmpID)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Comments comments = new Comments();

                    comments.ApplicationID = AppID;
                    comments.Comment = model.Comment;
                    comments.ApplicantVisible = model.ApplicantVisible;
                    comments.EmployeeID = EmpID;
                    comments.InsertDate = System.DateTime.Now;
                    comments.StatusID = 21;

                    db.Comments.Add(comments);
                    db.SaveChanges();

                    return RedirectToAction("Success", new { Type = "Comment", 
                                returnUrl = "ApplicationDetails_Comments", ID_01 = AppID });
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            
            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }
        #endregion

        #region JOBS
        // GET: /Employee/Jobs
        public ActionResult Jobs()
        {
            var jobs = db.Jobs.ToList();

            List<EmployeeJobModel> results = new List<EmployeeJobModel>();
            if (jobs != null)
            {
                results = jobs.ConvertAll(new Converter<Jobs, EmployeeJobModel>(JobToModel));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(results);
        }

        // GET: /Employee/JobDetails/8
        public ActionResult JobDetails(int id)
        {
            Jobs tempJob = db.Jobs.Find(id);
            EmployeeJobModel jobModel = new EmployeeJobModel(tempJob.ID, tempJob.Title, tempJob.Description, tempJob.InsertDate);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(jobModel);
        }

        // GET: /Employee/AddJob
        public ActionResult AddJob()
        {
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        // POST: /Employee/AddJob
        [HttpPost]
        public ActionResult AddJob(Create_JobModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Jobs job = new Jobs();

                    job.Description = model.Description;
                    job.Title = model.Title;
                    job.InsertDate = System.DateTime.Now;
                    job.ModifiedDate = System.DateTime.Now;
                    job.StatusID = 17;

                    db.Jobs.Add(job);
                    db.SaveChanges();

                    return RedirectToAction("MapQuestionsToJob", new { jobID = job.ID , newJob = true });
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            
            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }

        // GET: /Employee/EditJob
        public ActionResult EditJob(int id)
        {
            Jobs tempJob = db.Jobs.Find(id);
            Create_JobModel jobModel = new Create_JobModel(tempJob.Title, tempJob.Description);

            ViewBag.JobID = id;

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(jobModel);
        }

        // POST: /Employee/EditJob
        [HttpPost]
        public ActionResult EditJob(Create_JobModel model, int id)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Jobs job = db.Jobs.Find(id);

                    job.Description = model.Description;
                    job.Title = model.Title;
                    job.ModifiedDate = System.DateTime.Now;

                    db.SaveChanges();

                    return RedirectToAction("Success", new { Type = "Edit", returnUrl = "Jobs" });
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            
            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }
        #endregion

        #region JOB POSTINGS
        // GET: /Employee/JobPostings
        public ActionResult JobPostings()
        {
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }
        #region CHILDREN
        [ChildActionOnly]
        public PartialViewResult _ActivePostings()
        {
            var jobpostings = (from q in db.JobPostings where q.StatusID == 19 select q).ToList();

            List<SearchModel> postingModels = new List<SearchModel>();
            if (jobpostings != null)
            {
                postingModels = jobpostings.ConvertAll(new Converter<JobPostings, SearchModel>(DbSearchToViewSearch));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return PartialView("_ActivePostings", postingModels);
        }

        [ChildActionOnly]
        public PartialViewResult _PostingsAwaitingApproval()
        {
            var jobpostings = (from q in db.JobPostings where q.StatusID == 30 select q).ToList();

            List<SearchModel> postingModels = new List<SearchModel>();
            if (jobpostings != null)
            {
                postingModels = jobpostings.ConvertAll(new Converter<JobPostings, SearchModel>(DbSearchToViewSearch));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return PartialView("_PostingsAwaitingApproval", postingModels);
        }
        
        [ChildActionOnly]
        public PartialViewResult _ClosedPostings()
        {
            var jobpostings = (from q in db.JobPostings where q.StatusID == 31 select q).ToList();

            List<SearchModel> postingModels = new List<SearchModel>();
            if (jobpostings != null)
            {
                postingModels = jobpostings.ConvertAll(new Converter<JobPostings, SearchModel>(DbSearchToViewSearch));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return PartialView("_ActivePostings", postingModels);
        }
        
        [ChildActionOnly]
        public PartialViewResult _InactivePostings()
        {
            var jobpostings = (from q in db.JobPostings where q.StatusID == 20 select q).ToList();

            List<SearchModel> postingModels = new List<SearchModel>();
            if (jobpostings != null)
            {
                postingModels = jobpostings.ConvertAll(new Converter<JobPostings, SearchModel>(DbSearchToViewSearch));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return PartialView("_ActivePostings", postingModels);
        }
        #endregion

        // GET: /Employee/JobPostingDetails/3
        public ActionResult JobPostingDetails(int id)
        {
            JobPostings tempPosting = db.JobPostings.Find(id);
            EmployeeJobPostingModel postingModel = JobPostingToModel(tempPosting);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(postingModel);
        }

        // GET: /Employee/AddJobPosting
        public ActionResult AddJobPosting()
        {
            ViewBag.JobID = new SelectList(db.Jobs, "ID", "Title");
            ViewBag.LocationID = new SelectList(db.Locations, "ID", "City");

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        // POST: /Employee/AddJobPosting
        [HttpPost]
        public ActionResult AddJobPosting(Create_JobPostingModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    JobPostings jobPosting = new JobPostings();

                    jobPosting.Applications = new HashSet<Applications>();
                    jobPosting.JobPostingToQuestions = new HashSet<JobPostingToQuestions>();

                    jobPosting.InsertDate = System.DateTime.Now;
                    jobPosting.JobID = model.JobID;
                    jobPosting.LocationID = model.LocationID;
                    jobPosting.ModifiedDate = System.DateTime.Now;
                    jobPosting.StatusID = 30;

                    db.JobPostings.Add(jobPosting);
                    db.SaveChanges();

                    return RedirectToAction("Success", new { Type = "JobPosting", returnUrl = "JobPostings"});
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            
            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }

        // GET: /Employee/EditJobPosting
        public ActionResult EditJobPosting(int id)
        {
            JobPostings tempPosting = db.JobPostings.Find(id);
            Create_JobPostingModel postingModel = new Create_JobPostingModel(tempPosting.JobID, tempPosting.LocationID);

            ViewBag.PostingID = id;

                //Select List Items
            ViewBag.Jobs_SelectList = MakeSelectListFromJobs(db.Jobs.ToList(), postingModel.JobID);
            ViewBag.Locations_SelectList = MakeSelectListFromLocations(db.Locations.ToList(), postingModel.LocationID);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(postingModel);
        }

        // POST: /Employee/EditJobPosting
        [HttpPost]
        public ActionResult EditJobPosting(Create_JobPostingModel model, int id)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    JobPostings posting = db.JobPostings.Find(id);

                    posting.JobID = model.JobID;
                    posting.LocationID = model.LocationID;
                    posting.ModifiedDate = System.DateTime.Now;

                    db.SaveChanges();

                    return RedirectToAction("Success", new { Type = "JobPosting", returnUrl = "JobPostings" });
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            
            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }

        // GET: /Employee/ApprovePosting/6
        public ActionResult ApprovePosting(int id)
        {
            JobPostings tempPosting = db.JobPostings.Find(id);
            EmployeeJobPostingModel postingModel = JobPostingToModel(tempPosting);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(postingModel);
        }

        // GET: /Employee/ApprovalConfirmed/6
        public ActionResult ApprovalConfirmed(int id)
        {
            JobPostings posting = db.JobPostings.Find(id);

            posting.StatusID = 19;
            posting.ModifiedDate = System.DateTime.Now;

            db.SaveChanges();

            return RedirectToAction("Success", new { Type = "Approval", returnUrl = "JobPostings" });
        }
        #endregion

        #region QUESTIONS
        // GET: /Employee/Questions
        public ActionResult Questions()
        {
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        // GET: /Employee/ViewQuestions
        public ActionResult ViewQuestions()
        {
            List<Questions> tempQuestions = db.Questions.ToList();
            List<EmployeeQuestionModel> questionModels = new List<EmployeeQuestionModel>();

            if (tempQuestions != null)
            {
                foreach (var item in tempQuestions)
                {
                    List<Answers> tempAnswers = (from q in db.QuestionToAnswer where q.QuestionID == item.ID select q.Answers).ToList();
                    List<EmployeeAnswerModel> answerModels = new List<EmployeeAnswerModel>();
                    questionModels.Add(new EmployeeQuestionModel(item.ID, item.Question, item.InsertDate,
                                                tempAnswers.ConvertAll(new Converter<Answers,EmployeeAnswerModel>(DBAnswersToModel))));
                }
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(questionModels);
        }

        // GET: /Employee/JobList
        public ActionResult JobList()
        {
            List<Jobs> tempJobs = db.Jobs.ToList();
            List<SimpleJobModel> models = new List<SimpleJobModel>();

            if (tempJobs != null)
            {
                models = tempJobs.ConvertAll(new Converter<Jobs, SimpleJobModel>(DBJobToSimpleModel));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(models);
        }

        // GET: /Employee/AddQuestion
        public ActionResult AddQuestion()
        {
            List<Answers> tempAnswers = db.Answers.ToList();
            List<EmployeeSelectAnswerModel> answerModels = new List<EmployeeSelectAnswerModel>();

            if (tempAnswers != null)
            {
                answerModels = tempAnswers.ConvertAll(new Converter<Answers, EmployeeSelectAnswerModel>(DBAnswersToSelectModel));
            }

            Create_QuestionModel model = new Create_QuestionModel(null, answerModels);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }

        // POST: /Employee/AddQuestion
        [HttpPost]
        public ActionResult AddQuestion(Create_QuestionModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Questions question = new Questions();

                    question.AnswerRequired = 0;
                    question.FailSafe = 0;
                    question.InsertDate = System.DateTime.Now;
                    question.Question = model.Question;
                    question.ShortAnswer = 0;
                    question.StatusID = 3;

                    db.Questions.Add(question);

                    foreach (var item in model.Answers)
                    {
                        if (item.Selected)
                        {
                            QuestionToAnswer q2a = new QuestionToAnswer();

                            q2a.AnswerID = item.ID;
                            q2a.QuestionID = question.ID;
                            q2a.InsertDate = System.DateTime.Now;
                            q2a.StatusID = 26;

                            db.QuestionToAnswer.Add(q2a);
                        }
                    }
                    db.SaveChanges();

                    return RedirectToAction("Success", new { Type = "Question", returnUrl = "Questions" });
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }

            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }

        // GET: /Employee/MapQuestionsToJob
        public ActionResult ViewQuestionsToJob(int jobID)
        {
            List<Questions> tempQuestions = (from q in db.JobToQuestions where q.JobID == jobID select q.Questions).ToList(); 
            List<EmployeeSelectQuestionModel> selectModels = new List<EmployeeSelectQuestionModel>();

            if (tempQuestions != null)
            {
                selectModels = tempQuestions.ConvertAll(new Converter<Questions, EmployeeSelectQuestionModel>(QuestionToSelectModel));
            }

            EmployeeJobToQuestionModel EJTQM = new EmployeeJobToQuestionModel(
                                                        jobID, db.Jobs.Find(jobID).Description, selectModels);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(EJTQM);
        }

        // GET: /Employee/MapQuestionsToJob
        public ActionResult MapQuestionsToJob(int jobID, bool newJob)
        {
            List<Questions> tempQuestions = db.Questions.ToList();
            List<EmployeeSelectQuestionModel> selectModels = new List<EmployeeSelectQuestionModel>();

            if (tempQuestions != null)
            {
                selectModels = tempQuestions.ConvertAll(new Converter<Questions, EmployeeSelectQuestionModel>(QuestionToSelectModel));
            }

            foreach (var item in selectModels)
            {
                JobToQuestions temp = db.JobToQuestions.FirstOrDefault(x => x.JobID == jobID && x.QuestionID == item.QuestionID);
                if (temp != null)
                {
                    item.Selected = true;
                }
            }

            EmployeeJobToQuestionModel EJTQM = new EmployeeJobToQuestionModel(
                                                        jobID, db.Jobs.Find(jobID).Description, selectModels);

            ViewBag.NewJob = newJob;
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(EJTQM);
        }

        // POST: //Employee/MapQuestionsToJob
        [HttpPost]
        public ActionResult MapQuestionsToJob(EmployeeJobToQuestionModel model, int jobID)
        {
            try
            {
                if (ModelState.IsValid)
                {
                        //Delete previous records from JobsToQuestions Table
                    List<JobToQuestions> temp = (from q in db.JobToQuestions where q.JobID == jobID select q).ToList();
                    foreach (var item in temp)
                    {
                        db.JobToQuestions.Remove(item);
                        db.SaveChanges();
                    }

                        //Add new records
                    foreach (var item in model.Questions)
                    {
                        if (item.Selected)
                        {
                            JobToQuestions tempJobToQuestion = new JobToQuestions();

                            tempJobToQuestion.JobID = jobID;
                            tempJobToQuestion.QuestionID = item.QuestionID;
                            tempJobToQuestion.InsertDate = System.DateTime.Now;
                            tempJobToQuestion.StatusID = 26;

                            db.JobToQuestions.Add(tempJobToQuestion);
                            db.SaveChanges();
                        }
                    }
                    return RedirectToAction("Success", new { Type = "QuestionToJob", returnUrl = "Index" });
                }
            }
            catch (Exception ex)
            {

            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }
        #endregion

        #region LOCATIONS
        // GET: /Employee/Locations
        public ActionResult Locations()
        {
            var locations = db.Locations.ToList();

            List<EmployeeLocationModel> locationModels = new List<EmployeeLocationModel>();
            if (locations != null)
            {
                locationModels = locations.ConvertAll(new Converter<Locations, EmployeeLocationModel>(LocationToModel));
            }

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(locationModels);
        }

        // GET: /Employee/LocationDetails/9
        public ActionResult LocationDetails(int id)
        {
            Locations tempLocation = db.Locations.Find(id);
            EmployeeLocationModel locationModel = LocationToModel(tempLocation);

            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(locationModel);
        }

        // GET: /Employee/AddLocation
        public ActionResult AddLocation()
        {
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        // POST: /Employee/AddLocation
        [HttpPost]
        public ActionResult AddLocation(Create_LocationModel model)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    Locations Location = new Locations();

                    Location.City = model.City;
                    Location.InsertDate = System.DateTime.Now;
                    Location.Region = model.Region;
                    Location.State = model.State;
                    Location.StatusID = 26;

                    db.Locations.Add(Location);
                    db.SaveChanges();

                    return RedirectToAction("Success", new { Type = "Location", returnUrl = "Locations" });
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", e.Message);
            }
            
            // If we got this far, something failed, redisplay form
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }
        #endregion

        #region USERS
        // GET: /Employee/Users
        public ActionResult Users()
        {
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }
        #region CHILDREN
            [ChildActionOnly]
            public PartialViewResult _Applicants()
        {
            List<Users> tempApplicants = (from q in db.Users where q.UserTypeID == 1 && q.StatusID == 1 select q).ToList();

            List<EmployeeUserModel> applicantModels = new List<EmployeeUserModel>();

            if (tempApplicants != null)
            {
                applicantModels = tempApplicants.ConvertAll(new Converter<Users, EmployeeUserModel>(UserToModel));
            }

            return PartialView("_Applicants", applicantModels);
        }
        
            [ChildActionOnly]
            public PartialViewResult _Employees()
        {
            List<Users> tempEmployees = (from q in db.Users where q.UserTypeID > 1 select q).ToList();

            List<EmployeeAccountModel> employeeModels = new List<EmployeeAccountModel>();

            if (tempEmployees != null)
            {
                employeeModels = tempEmployees.ConvertAll(new Converter<Users, EmployeeAccountModel>(EmployeeUserToModel));
            }


            return PartialView("_Employees", employeeModels);
        }

            [ChildActionOnly]
            public PartialViewResult _InactiveApplicants()
        {
            List<Users> tempApplicants = (from q in db.Users where q.UserTypeID == 1 && q.StatusID == 2 select q).ToList();

            List<EmployeeUserModel> applicantModels = new List<EmployeeUserModel>();

            if (tempApplicants != null)
            {
                applicantModels = tempApplicants.ConvertAll(new Converter<Users, EmployeeUserModel>(UserToModel));
            }

            return PartialView("_InactiveApplicants", applicantModels);
        }
        #endregion

        // GET: /Employee/ApplicantDetails
        public ActionResult ApplicantDetails(int id)
        {
            Users tempUser = db.Users.Find(id);
            EmployeeUserModel userModel = new EmployeeUserModel();

            if (tempUser != null)
            {
                userModel = UserToModel(tempUser);
            }
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));

            return View(userModel);
        }

        // GET: /Employee/EmployeeDetails
        public ActionResult EmployeeDetails(int id)
        {
            Users tempUser = db.Users.Find(id);
            EmployeeAccountModel userModel = new EmployeeAccountModel();

            if (tempUser != null)
            {
                userModel = EmployeeUserToModel(tempUser);
            }
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));

            return View(userModel);
        }
        #endregion

        #region HIRING
        // GET: /Employee/SelectApplicant
        public ActionResult SelectApplicant(int postingID)
        {
            List<Applications> tempApplications = (from q in db.Applications where q.JobPostingID == postingID select q).ToList();
            List<HiringSpecialistAppModel> appModels = new List<HiringSpecialistAppModel>();

            if (tempApplications != null)
            {
                appModels = tempApplications.ConvertAll(new Converter<Applications, HiringSpecialistAppModel>(DbSearchToHSAMSearch));
            }

            ViewBag.PostingID = postingID;
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(appModels);
        }

        // GET: /Employee/HireConfirm
        public ActionResult HireConfirm(int postingID, int appID)
        {
            Applications tempApplication = db.Applications.Find(appID);
            JobPostings tempPosting = db.JobPostings.Find(postingID);
            bool bgCheck;
            if (tempApplication.StatusID == 33)
            {
                bgCheck = true;

            }
            else
            {
                bgCheck = false;
            }

            EmployeeHiringModel model = new EmployeeHiringModel(tempApplication.Users.FirstName, tempApplication.Users.LastName,
                                                tempPosting.Jobs.Title, tempPosting.Locations.City, tempApplication.InsertDate, bgCheck);

            ViewBag.PostingID = postingID;
            ViewBag.ApplicationID = appID;
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View(model);
        }

        // GET: /Employee/ClosePosting
        public ActionResult ClosePosting(int postingID, int appID)
        {
            try
            {
                int tempJobID = db.JobPostings.Find(postingID).JobID;
                int tempLocationID = db.JobPostings.Find(postingID).LocationID;
                string userName = db.Applications.Single(x => x.ID == appID).Users.UserName;

                //Close JobPosting
                JobPostings tempPosting = db.JobPostings.Find(postingID);
                tempPosting.StatusID = 31;
                db.SaveChanges();

                //Set accepted application to correct status
                Applications winner = db.Applications.Find(appID);
                winner.StatusID = 24;
                db.SaveChanges();

                //Find other applications for this job from same user
                List<Applications> toClose_ThisUser = (from q in db.Applications
                                                       where
                                                             (q.JobPostings.JobID == tempJobID
                                                             && q.JobPostings.LocationID == tempLocationID
                                                             && q.ID != appID
                                                             && q.Users.UserName == userName)
                                                       select q).ToList();
                //Set those applications to closed
                if (!toClose_ThisUser.Count.Equals(0))
                {
                    foreach (var item in toClose_ThisUser)
                    {
                        item.StatusID = 32;
                        db.SaveChanges();
                    }
                }

                //Find applications for this job postings from other users
                List<Applications> toClose_OtherUsers = (from q in db.Applications
                                                         where
                                                              (q.JobPostingID == postingID
                                                              && q.Users.UserName != userName)
                                                         select q).ToList();
                
                //Set those applications to status "denied"
                if (!toClose_OtherUsers.Count.Equals(0))
                {
                    foreach (var item in toClose_OtherUsers)
                    {
                        item.StatusID = 25;
                        db.SaveChanges();
                    }
                }

                db.SaveChanges();
                return RedirectToAction("Success", new { Type = "Hire", returnUrl = "JobPostings" });
            }
            catch (Exception ex)
            {
                
            }

                // If we got this far, something failed, return to JobPostings
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return RedirectToAction("JobPostings");
        }

        #endregion

        #region BACKGROUND CHECK
        // GET: Employee/BackgroundCheck/6
        public ActionResult BackgroundCheck(int id)
        {
            ViewBag.ApplicationID = id;
            ViewData.Add("AccessLevel", Session.GetDataFromSession<string>("AccessLevel"));
            return View();
        }

        // GET: Employee/PerformBGCheck/6
        public ActionResult PerformBGCheck(int id, bool success)
        {
            Applications tempApp = db.Applications.Find(id);
            int tempPostingID = tempApp.JobPostingID;
            int tempJobID = tempApp.JobPostings.JobID;
            int tempLocationID = tempApp.JobPostings.LocationID;
            string tempUserName = tempApp.Users.UserName;

            //Find other applications for this job by same user
            List<Applications> tempApplications = (from a in db.Applications
                                                    where
                                                  (a.JobPostings.JobID == tempJobID
                                                  && a.JobPostings.LocationID == tempLocationID
                                                  && a.Users.UserName == tempUserName)
                                                    select a).ToList();

            //Set application(s) to appropriate status
            if (!tempApplications.Count.Equals(0))
            {
                foreach (var item in tempApplications)
                {
                    if (success)
                    {
                        item.StatusID = 33;
                        db.SaveChanges();
                    }
                    else
                    {
                        item.StatusID = 25;
                        db.SaveChanges();
                        return RedirectToAction("Success", new { Type = "BGFail", returnUrl = "Applications" });
                    }
                }
            }

            if (success)
            {
                return RedirectToAction("Success", new
                {
                    Type = "BGSuccess",
                    returnUrl = "ApplicationDetails_Home",
                    ID_01 = id
                });
            }
            else
            {
                return RedirectToAction("Success", new 
                { 
                    Type = "BGFail",
                    returnUrl = "Applications" 
                });
            }
        }
        #endregion

        #region HELPERS
        #region MODEL CREATORS
        private HiringSpecialistAppModel DbSearchToHSAMSearch(Applications db)
        {
            return new HiringSpecialistAppModel(db, db.Users, db.JobPostings);
        }
        
        private EmployeeBasicApplicationModel BasicApplicationInfoToApplicationModel(BasicApplicationInfo Bai)
        {
            EmployeeBasicApplicationModel Ebam = new EmployeeBasicApplicationModel();
            Ebam.AltName = Bai.AltName;
            Ebam.Days = Convert.ToBoolean(Bai.Days);
            Ebam.Evenings = Convert.ToBoolean(Bai.Evenings);
            Ebam.FullTime = Convert.ToBoolean(Bai.FullTime);
            Ebam.MonStart = Bai.MonStart;
            Ebam.MonStop = Bai.MonStop;
            Ebam.TuesStart = Bai.TuesStart;
            Ebam.TuesStop = Bai.TuesStop;
            Ebam.WedStart = Bai.WedStart;
            Ebam.WedStop = Bai.WedStop;
            Ebam.ThurStart = Bai.ThurStart;
            Ebam.ThurStop = Bai.ThurStop;
            Ebam.FriStart = Bai.FriStart;
            Ebam.FriStop = Bai.FriStop;
            Ebam.SatStart = Bai.SatStart;
            Ebam.SatStop = Bai.SatStop;
            Ebam.SunStart = Bai.SunStart;
            Ebam.SunStop = Bai.SunStop;
            Ebam.SSN = Bai.SSN;
            Ebam.EmployerName1 = Bai.EmploymentHistory.Name;
            Ebam.Position1 = Bai.EmploymentHistory.Position;
            Ebam.StartDate1 = Bai.EmploymentHistory.StartDate;
            Ebam.EndDate1 = Bai.EmploymentHistory.EndDate;
            Ebam.Address11 = Bai.EmploymentHistory.Address1;
            Ebam.Address21 = Bai.EmploymentHistory.Address2;
            Ebam.City1 = Bai.EmploymentHistory.City;
            Ebam.State1 = Bai.EmploymentHistory.State;
            Ebam.Zip1 = Bai.EmploymentHistory.Zip;
            Ebam.ManagerName1 = Bai.EmploymentHistory.ManagerName;
            Ebam.ManagerPhone1 = Bai.EmploymentHistory.Phone;
            Ebam.StartSalary1 = Bai.EmploymentHistory.StartSalary;
            Ebam.EndSalary1 = Bai.EmploymentHistory.EndSalary;
            Ebam.ReasonForLeaving1 = Bai.EmploymentHistory.ReasonForLeaving;
            Ebam.Responsibilities1 = Bai.EmploymentHistory.Responsibilities;
            Ebam.MayWeContact1 = Convert.ToBoolean(Bai.EmploymentHistory.MayWeContact);
            Ebam.SchoolName1 = Bai.Education.SchoolName;
            Ebam.SchoolAddress11 = Bai.Education.Address1;
            Ebam.SchoolAddress21 = Bai.Education.Address2;
            Ebam.SchoolCity1 = Bai.Education.City;
            Ebam.SchoolState1 = Bai.Education.State;
            Ebam.SchoolZip1 = Bai.Education.Zip;
            Ebam.YearStart1 = Bai.Education.YearStart;
            Ebam.YearEnd1 = Bai.Education.YearEnd;
            Ebam.Graduated1 = Convert.ToBoolean(Bai.Education.Graduated);
            return Ebam;
        }
        
        private EmployeeDetailedApplicationModel DetailedApplicationToDetailedApplicationModel(Applications Dai)
        {
            EmployeeDetailedApplicationModel Edam = new EmployeeDetailedApplicationModel();

            Edam.Address1 = Dai.Users.Addresses.Single(x => x.UserID == Dai.UserID).Address1;
            Edam.Address2 = Dai.Users.Addresses.Single(x => x.UserID == Dai.UserID).Address2;
            Edam.ApplicantPhoneNumber1 = Dai.PhoneNumbers.Number;
            if (Dai.PhoneNumbers1 != null)
            {
                Edam.ApplicantPhoneNumber2 = Dai.PhoneNumbers1.Number;
            }
            Edam.City = Dai.Users.Addresses.Single(x => x.UserID == Dai.UserID).City;
            Edam.DesiredSalary = Dai.Salary;
            Edam.ReferenceCompanyName1 = Dai.References.Company;
            Edam.ReferenceCompanyName2 = Dai.References1.Company;
            Edam.ReferenceCompanyName3 = Dai.References2.Company;
            Edam.ReferenceJobTitle1 = Dai.References.Title;
            Edam.ReferenceJobTitle2 = Dai.References1.Title;
            Edam.ReferenceJobTitle3 = Dai.References2.Title;
            Edam.ReferenceName1 = Dai.References.Name;
            Edam.ReferenceName2 = Dai.References1.Name;
            Edam.ReferenceName3 = Dai.References2.Name;
            Edam.ReferencePhoneNumber1 = Dai.References.Phone;
            Edam.ReferencePhoneNumber2 = Dai.References1.Phone;
            Edam.ReferencePhoneNumber3 = Dai.References2.Phone;
            Edam.State = Dai.Users.Addresses.Single(x => x.UserID == Dai.UserID).City;
            Edam.Zip = Dai.Users.Addresses.Single(x => x.UserID == Dai.UserID).Zip;

            return Edam;
        }

        private EmployeeJobModel JobToModel(Jobs Job)
        {
            return new EmployeeJobModel(Job.ID, Job.Title, Job.Description, Job.InsertDate);
        }

        private EmployeeJobPostingModel JobPostingToModel(JobPostings Posting)
        {
            EmployeeJobPostingModel Ejpm = new EmployeeJobPostingModel();

            Ejpm.ID = Posting.ID;
            Ejpm.JobID = Posting.JobID;
            Ejpm.JobTitle = Posting.Jobs.Title;
            Ejpm.LocationCity = Posting.Locations.City;
            Ejpm.LocationState = Posting.Locations.State;
            Ejpm.PostingDate = Posting.InsertDate;

            return Ejpm;
        }
        
        private EmployeeUserModel UserToModel(Users User)
        {
            EmployeeUserModel Eum = new EmployeeUserModel();

            Eum.EMail = User.Email;
            Eum.FirstName = User.FirstName;
            Eum.ID = User.ID;
            Eum.InsertDate = User.InsertDate;
            Eum.LastName = User.LastName;
            Eum.MiddleName = User.MiddleName;
            Eum.UserName = User.UserName;
                
            return Eum;
        }

        private EmployeeAccountModel EmployeeUserToModel(Users User)
        {
            EmployeeAccountModel Eam = new EmployeeAccountModel();

            Eam.AccessLevel = User.UserTypeID;
            Eam.FirstName = User.FirstName;
            Eam.ID = User.ID;
            Eam.LastName = User.LastName;
            Eam.UserName = User.UserName;

            return Eam;
        }
        
        private EmployeeQuestionnaireModel QuestionnaireToModel(UserResponses Responses)
        {
            EmployeeQuestionnaireModel Eqm = new EmployeeQuestionnaireModel();
            Eqm.ApplicationID = Responses.ApplicationID;
            Eqm.ID = Responses.ID;
            Eqm.Question = Responses.Questions.Question;
            Eqm.UserID = Responses.UserID;
            Eqm.Answer = Responses.Answers.Answer;

            return Eqm;
        }
        
        private EmployeeCommentModel CommentToModel(Comments Comment)
        {
            EmployeeCommentModel Ecm = new EmployeeCommentModel();
            Ecm.ApplicationID = Comment.ApplicationID;
            Ecm.Comment = Comment.Comment;
            Ecm.ApplicantVisible = Comment.ApplicantVisible;
            Ecm.Employee = db.Users.Single(x => x.ID == Comment.EmployeeID).UserName;
            Ecm.InsertDate = Comment.InsertDate;

            return Ecm;
        }

        private SearchModel DbSearchToViewSearch(JobPostings db)
        {
            return new SearchModel(db.JobID, db.ID, db.Jobs.Title, db.Jobs.Description, db.Locations.City,
                                    db.InsertDate, db.ModifiedDate);
        }

        private EmployeeLocationModel LocationToModel(Locations Location)
        {
            return new EmployeeLocationModel(Location.ID, Location.City, Location.State, Location.Region, Location.InsertDate);
        }

        private EmployeeSelectQuestionModel QuestionToSelectModel(Questions Question)
        {
            return new EmployeeSelectQuestionModel(Question.ID, Question.Question, false);
        }

        private SimpleJobModel DBJobToSimpleModel(Jobs Job)
        {
            return new SimpleJobModel(Job.ID, Job.Title);
        }

        private EmployeeSelectAnswerModel DBAnswersToSelectModel(Answers Answer)
        {
            return new EmployeeSelectAnswerModel(Answer.ID, Answer.Answer, false);
        }
        
        private EmployeeAnswerModel DBAnswersToModel(Answers Answer)
        {
            return new EmployeeAnswerModel(Answer.ID, Answer.Answer);
        }
        #endregion

        #region SELECT LIST CREATORS
        private List<SelectListItem> MakeSelectListFromJobs(List<Jobs> jobs, int selectedID)
        {
            List<SelectListItem> tempSelectListItems = new List<SelectListItem>();
            foreach(var item in jobs)
            {
                SelectListItem ListItem = new SelectListItem();
                if (item.ID == selectedID)
                {
                    ListItem.Selected = true;
                }
                else
                {
                    ListItem.Selected = false;
                }
                ListItem.Text = item.Title;
                ListItem.Value = item.ID.ToString();

                tempSelectListItems.Add(ListItem);
            }

            return tempSelectListItems;
        }

        private List<SelectListItem> MakeSelectListFromLocations(List<Locations> locations, int selectedID)
        {
            List<SelectListItem> tempSelectListItems = new List<SelectListItem>();
            foreach (var item in locations)
            {
                SelectListItem ListItem = new SelectListItem();
                if (item.ID == selectedID)
                {
                    ListItem.Selected = true;
                }
                else
                {
                    ListItem.Selected = false;
                }
                ListItem.Text = item.City;
                ListItem.Value = item.ID.ToString();

                tempSelectListItems.Add(ListItem);
            }

            return tempSelectListItems;
        }
        #endregion
        #endregion
    }
}
